﻿using Furion;
using Furion.CMS.EntityFramework.Core;
using Furion.DatabaseAccessor;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace Microsoft.EntityFrameworkCore.Metadata.Builders
{
    public static class EntityTypeBuilderExtension
    {
        /// <summary>
        /// 使用默认表名称定义
        /// <para>根据实体名称生成默认的数据表映射名称</para>
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="self"></param>
        /// <returns></returns>
        public static EntityTypeBuilder<T> UseDefaultTableNameDefine<T>(this EntityTypeBuilder<T> self)
            where T : class
        {
            var dbTableName = typeof(T).Name.Replace(DatabaseConsts.IgnoreSuffix, "");
            self.ToTable($"{DatabaseConsts.DbTablePrefix}{dbTableName}{(dbTableName.EndsWith("list") || dbTableName.EndsWith("List") ? "" : "s")}");
            return self;
        }

        /// <summary>
        /// 外键关系约束控制
        /// <para>
        /// 可控制是否生成外键约束
        /// 若不生成外键则只做导航属性
        /// </para>
        /// </summary>
        /// <typeparam name="TPrincipalEntity"></typeparam>
        /// <typeparam name="TDependentEntity"></typeparam>
        /// <param name="builder"></param>
        /// <param name="foreignKeyExpression"></param>
        /// <param name="isGenerate"></param>
        /// <returns></returns>
        public static ReferenceCollectionBuilder<TPrincipalEntity, TDependentEntity> HasForeignKey<TPrincipalEntity, TDependentEntity>(this ReferenceCollectionBuilder<TPrincipalEntity, TDependentEntity> builder,
            Expression<Func<TDependentEntity, object>> foreignKeyExpression, bool isGenerate)
            where TPrincipalEntity : class
            where TDependentEntity : class
        {
            if (!isGenerate)
            {
                if (foreignKeyExpression.Body is UnaryExpression unary && unary.Operand is MemberExpression member)
                {
                    var entityName = foreignKeyExpression.Parameters.FirstOrDefault()?.Type.FullName;
                    if (!string.IsNullOrWhiteSpace(entityName))
                    {
                        var foreignKey = member.Member.Name;
                        RemoveForeignKeysHelper.RemoveForeignKeys.AddOrUpdate(entityName, new List<string> { foreignKey }, (value, values) =>
                        {
                            values.Add(foreignKey);
                            return values.Distinct().ToList();
                        });
                    }
                }
            }

            return builder.HasForeignKey(foreignKeyExpression);
        }
    }
}
